﻿#pragma once
/// Copyright 2012, Alex Averian, Yonan Research
/// Released under BSD Licence



#include "qrect.h"  //for QSize
#include "qstring.h"
using namespace micro::utils;


namespace micro
{
namespace gui
{


class QBitmap
{
    HBITMAP m_hBitmap;

public:


    QBitmap( HBITMAP hBitmap = nullptr )
    {
        m_hBitmap = hBitmap;
    }

    ~QBitmap()
    {
        if( m_hBitmap )
            ::DeleteObject( m_hBitmap );
    }
    void Attach( HBITMAP hBitmap )
    {
        m_hBitmap = hBitmap;
    }
    HBITMAP Dettach()
    {
        HBITMAP hBitmap = m_hBitmap;
        m_hBitmap = nullptr;
        return hBitmap;
    }
    bool SaveImage( QString & path );
	bool CopyToClipboard();



    inline operator HBITMAP()
    {
        return m_hBitmap;
    }
    inline operator HGDIOBJ()
    {
        return m_hBitmap;
    }

    inline bool IsValidBitmap()
    {
        return  ( m_hBitmap != nullptr );
    }

    HBITMAP GetBitMap()
    {
        if ( IsValidBitmap() ) return m_hBitmap;
        return nullptr;
    }

    HBITMAP GetSafeHandle()
    {
        if ( IsValidBitmap() ) return m_hBitmap;
        return nullptr;
    }
    HBITMAP LoadBitmap( LPCTSTR lpBitmapName, HINSTANCE hInsTance = GetModuleHandle( 0 ) )
    {
        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::LoadBitmap( hInsTance, lpBitmapName );
        return m_hBitmap;
    }

    HBITMAP LoadBitmap( UINT nIDBitmap )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::LoadBitmap( GetModuleHandle( 0 ) , MAKEINTRESOURCE( nIDBitmap ) );
        return m_hBitmap;
    }

    HBITMAP CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitcount,  void* lpBits )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateBitmap( nWidth, nHeight, nPlanes, nBitcount, lpBits );
        return m_hBitmap;
    }

    bool DeleteObject()
    {
        if ( !IsValidBitmap() ) return false;
        ::DeleteObject( m_hBitmap );

        m_hBitmap  = nullptr;
        return true;
    }

    int GetBitmap( BITMAP* pBitMap )
    {
        if ( !IsValidBitmap() ) return FALSE;
        return ::GetObject( m_hBitmap, sizeof( BITMAP ), pBitMap );
    }

    bool GetBitmap( BITMAP& bm )
    {
        if ( !IsValidBitmap() ) return false;
        return ( ::GetObject( m_hBitmap, sizeof( BITMAP ), &bm ) == sizeof( BITMAP ) );
    }

    bool GetSize( SIZE& size )
    {
        if ( !IsValidBitmap() ) return false;
        BITMAP bm;
        if( !GetBitmap( &bm ) )
            return FALSE;
        size.cx = bm.bmWidth;
        size.cy = bm.bmHeight;
        return true;
    }

    QSize GetSize()
    {
        if ( !IsValidBitmap() ) return QSize( 0, 0 );
        BITMAP bm;
        if( !GetBitmap( &bm ) )
            return QSize( 0, 0 );
        return QSize( bm.bmWidth, bm.bmHeight );
    }


    DWORD GetBitmapBits( DWORD dwCount, LPVOID lpBits )
    {
        if ( !IsValidBitmap() ) return 0;
        return ::GetBitmapBits( m_hBitmap, dwCount, lpBits );
    }
    DWORD SetBitmapBits( DWORD dwCount,  void* lpBits )
    {
        if ( !IsValidBitmap() ) return 0;
        return ::SetBitmapBits( m_hBitmap, dwCount, lpBits );
    }
    BOOL GetBitmapSize( QSize& size )
    {
        if ( !IsValidBitmap() ) return FALSE;
        return ::GetBitmapDimensionEx( m_hBitmap, size );
    }
    BOOL SetBitmapSize( int nWidth, int nHeight, LPSIZE lpSize = nullptr )
    {
        if ( !IsValidBitmap() ) return FALSE;
        return ::SetBitmapDimensionEx( m_hBitmap, nWidth, nHeight, lpSize );
    }

    HBITMAP CreateBitmapIndirect( LPBITMAP lpBitmap )
    {
        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateBitmapIndirect( lpBitmap );
        return m_hBitmap;
    }
    HBITMAP CreateCompatibleBitmap( HDC hDC, int nWidth, int nHeight )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateCompatibleBitmap( hDC, nWidth, nHeight );
        return m_hBitmap;
    }
    HBITMAP CreateDiscardableBitmap( HDC hDC, int nWidth, int nHeight )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateDiscardableBitmap( hDC, nWidth, nHeight );
        return m_hBitmap;
    }


    HBITMAP CreateDIBitmap( HDC hDC,  BITMAPINFOHEADER* lpbmih, DWORD dwInit,  VOID* lpbInit,  BITMAPINFO* lpbmi, UINT uColorUse )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateDIBitmap( hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse );
        return m_hBitmap;
    }
    HBITMAP CreateDIBSection( HDC hDC,  BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset )
    {

        if ( IsValidBitmap() ) return nullptr;
        m_hBitmap = ::CreateDIBSection( hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset );
        return m_hBitmap;
    }
    int GetDIBits( HDC hDC, UINT uStartScan, UINT cScanLines,  LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse )
    {
        if ( !IsValidBitmap() ) return 0;
        return ::GetDIBits( hDC, m_hBitmap, uStartScan, cScanLines,  lpvBits, lpbmi, uColorUse );
    }
    int SetDIBits( HDC hDC, UINT uStartScan, UINT cScanLines,  VOID* lpvBits,  BITMAPINFO* lpbmi, UINT uColorUse )
    {
        if ( !IsValidBitmap() ) return 0;
        return ::SetDIBits( hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse );
    }

};


class QIcon
{
    HICON m_hIcon;
    bool m_destroy;
public:


    QIcon( HICON hicon = nullptr )
    {
        m_destroy  =  ( m_hIcon = hicon ) ? true : false;
    }

    ~QIcon()
    {
        if( m_destroy )  ::DeleteObject( m_hIcon );
    }

    inline operator HICON()
    {
        return m_hIcon;
    }

    void  Attach( HICON hIcon )
    {
        m_hIcon = hIcon;
    }
    HICON Dettach()
    {
        HICON hIcon = m_hIcon;
        m_hIcon = nullptr;
        return hIcon;
    }


};




}
}